﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using Telerik.WinControls;
using Pakxel.Data;
using Telerik.WinControls.UI;
using Pakxel.Framework;
using Pakxel.SmartLogistic.Admon;
using System.Data.Common;
using Telerik.WinControls.Data;

namespace Pakxel.SmartLogistic
{
    public partial class CxCWorkBench : Telerik.WinControls.UI.RadForm
    {
       private delegate bool RuleManager(string CString);
       private Pakxel.Framework.Rules ruleToCheck;
       private RuleManager IsNumeric;
       private MEDataDataContext DataContext;
       private UIHelper uiHelper;
       private T025 currRecord;
       private bool DeletingRow = false;
        public CxCWorkBench()
        {
            InitializeComponent();
        }

        private void SetupCobrosGridView()
        {
           CobrosGridView.AllowEditRow = false;
           CobrosGridView.AutoGenerateColumns = false;

           GridViewDateTimeColumn colT029Fecha = new GridViewDateTimeColumn("T029Fecha", "T029Fecha");
           colT029Fecha.HeaderText = "Fecha";
           colT029Fecha.FormatInfo = new System.Globalization.CultureInfo("es-MX");
           colT029Fecha.FormatString = "{0:dd/MM/yyyy}";
           colT029Fecha.Width = 400;

           GridViewDecimalColumn colT029Anticipo = new GridViewDecimalColumn("T029Anticipo", "T029Anticipo");
           colT029Anticipo.HeaderText = "Monto";
           colT029Anticipo.FormatInfo = new System.Globalization.CultureInfo("es-MX");
           colT029Anticipo.FormatString = "{0:C}";
           colT029Anticipo.Width = 400;

           try
           {
              CobrosGridView.Columns.Add(colT029Fecha);
              CobrosGridView.Columns.Add(colT029Anticipo);
              foreach (GridViewDataColumn col in this.CobrosGridView.Columns)
              {
                 col.BestFit();
              }
           }
           catch (SystemException se)
           {
              MainApp.WriteExceptionToLog(se);
           }
        }

        void SetUpEntidadesComboBox()
        {
           CatT011Entity.AutoFilter = true;
           // Obtener Combobox interno
           RadMultiColumnComboBoxElement Combo = CatT011Entity.MultiColumnComboBoxElement;
           CatT011Entity.AutoSizeDropDownToBestFit = true;
           Combo.EditorControl.MasterTemplate.AutoGenerateColumns = false;

           // Agregar Columnas
           GridViewTextBoxColumn column = new GridViewTextBoxColumn("T011Entity") { HeaderText = "Id Entidad" };
           Combo.Columns.Add(column);
           column = new GridViewTextBoxColumn("T011Nombre") { HeaderText = "Nombre(s)" };
           Combo.Columns.Add(column);
           column = new GridViewTextBoxColumn("T011RFC") { HeaderText = "RFC" };
           Combo.Columns.Add(column);
           // Obtener datos

           /// TODO : Solo los proveedores
           CatT011Entity.DataSource = (from E in DataContext.T011s select new { T011Entity = E.T011Entity, T011Nombre = E.T011Nombre, T011RFC = E.T011RFC });

           // Definir Campo de Busqueda y campo de seleccion
           CatT011Entity.DisplayMember = "T011Nombre";
           CatT011Entity.ValueMember = "T011Entity";

           // Definir Filtro de busqueda
           Combo.EditorControl.FilterDescriptors.Add(new FilterDescriptor(CatT011Entity.DisplayMember, FilterOperator.StartsWith, string.Empty));
           CatT011Entity.MultiColumnComboBoxElement.AutoCompleteMode = AutoCompleteMode.None;
           CatT011Entity.DropDownStyle = RadDropDownStyle.DropDown;
           //uiHelper.SetComboBoxFilter(ref CatT011Entity, "T011Entity", 1);
        }

        private void UpdateGraph()
        {
           try
           {
              cxcGraph.Series[0].Points.Clear();
              decimal? Facturado = DataContext.T025s.Sum(F => F.T025Importe);
              /// TODO : Corregir
              decimal? Anticipos = (decimal?)DataContext.T029s.Sum(A => A.T029Anticipo) ?? 0.0m;
              decimal? Vencido = 0.0m;
              DataContext.GetImporteVencidoCxC(ref Vencido);
              cxcGraph.Series[0].Points.Add(new DevExpress.XtraCharts.SeriesPoint("Pendiente", Facturado - Anticipos));
              cxcGraph.Series[0].Points.Add(new DevExpress.XtraCharts.SeriesPoint("Al Corriente", Anticipos));
              cxcGraph.Series[0].Points.Add(new DevExpress.XtraCharts.SeriesPoint("Vencido", Vencido));
           }
           catch (SystemException se)
           {
              MainApp.WriteExceptionToLog(se);
           }
        }

        private void SetupWorkBench()
        {
           uiHelper.ClearControls(gpoCxC.Controls);
           SetUpEntidadesComboBox();
           SetupCobrosGridView();
           UpdateGraph();
        }

        private void CxPWorkBench_Load(object sender, EventArgs e)
        {
           WorkBenchFilter.TextBox.BackColor = Color.LightYellow;
           DataContext = new MEDataDataContext(WorkBench.ConnectionString);
           FilterSelector.SelectedIndex = 0;
           ruleToCheck = new Rules();
           IsNumeric += new RuleManager(ruleToCheck.IsNumeric);
           uiHelper = new UIHelper();
           SetupWorkBench();
        }

        private void UpdateSaldo()
        {
           if (currRecord != null)
           {
              var Anticipos = (from P in DataContext.T029s
                               where P.T025Id.Equals(currRecord.T025Id)
                               select P);
              if (Anticipos != null)
              {
                 var Suma = Anticipos.Sum(s => (decimal?)s.T029Anticipo) ?? 0m;
                 SaldoFactura.Text = string.Format("{0:C}", currRecord.T025Importe - Suma);
              }
              else
              {
                 SaldoFactura.Text = string.Format("{0:C}", 0);
              }
           }
        }

        private void UpdateSaldoGridView()
        {
            if (currRecord != null)
            {
                decimal Saldo = 0;
                foreach (Telerik.WinControls.UI.GridViewRowInfo Row in CobrosGridView.Rows)
                {
                    Saldo += Convert.ToDecimal(Row.Cells["T029Anticipo"].Value);
                }
                SaldoFactura.Text = string.Format("{0:C}", currRecord.T025Importe - Saldo);
            }
        }

        private void ShowCxPRecord(T025 T025Record)
        {
           if (T025Record != null)
           {
              CatT011Entity.Text = T025Record.T011Entity.ToString();
              T025FechaIngreso.DateTime = T025Record.T025FechaIngreso;
              T025NoFactura.Text = T025Record.T025NoFactura;
              T025Importe.Text = string.Format("{0:C}", T025Record.T025Importe);
              UpdateSaldo();
              /// TODO : Hack para aplicar filtro con el mismo indice que el elemento seleccionado
              var Indice = CatT011Entity.SelectedIndex;
              uiHelper.SetComboBoxFilter(ref CatT011Entity, "T011Entity", T025Record.T011Entity);
              CatT011Entity.SelectedIndex = -1;
              CatT011Entity.SelectedIndex = Indice;
              CobrosGridView.DataSource = T025Record.T029s;
              foreach (GridViewDataColumn col in this.CobrosGridView.Columns)
              {
                 col.BestFit();
              }
           }
           else
           {
              uiHelper.ClearControls(this.Controls);
              statusMsg.Text = string.Empty;
           }
        }

        private void WorkBenchFilter_KeyDown(object sender, KeyEventArgs e)
        {
           if (e.KeyCode == Keys.Enter)
           {
              var T011Entity = (int)CatT011Entity.EditorControl.Rows[CatT011Entity.SelectedIndex].Cells["T011Entity"].Value;
              currRecord = (from F in DataContext.T025s
                            where F.T011.T011Entity.Equals(T011Entity)
                                && F.T025NoFactura.Equals(WorkBenchFilter.Text)
                            select F).SingleOrDefault();
              if (currRecord != null)
              {
                 ShowCxPRecord(currRecord);
                 statusMsg.Text = string.Empty;
              }
              else
              {
                 uiHelper.ClearControls(gpoCxC.Controls);
                 uiHelper.ClearComboBoxFilter(ref CatT011Entity);
                 CobrosGridView.DataSource = null;
                 statusMsg.Text = string.Format("No existe la factura {0}", WorkBenchFilter.Text);
              }
           }
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
           /// TODO : Validar Campos 
           if (currRecord == null)
           {
              if (DataContext.Connection.State != ConnectionState.Closed)
              {
                 DataContext.Connection.Close();
                 DataContext.Connection.Open();
              }
              else
                 DataContext.Connection.Open();
              /// TODO : Es necesaria la transaccion ? , ... no se hace uso de folios
              using (DbTransaction transaction = DataContext.Connection.BeginTransaction(IsolationLevel.Serializable))
              {
                 DataContext.Transaction = transaction;
                 try
                 {
                    currRecord = new T025();
                    currRecord.T011Entity = (int)CatT011Entity.EditorControl.Rows[CatT011Entity.SelectedIndex].Cells["T011Entity"].Value;
                    currRecord.T025FechaIngreso = T025FechaIngreso.DateTime;
                    currRecord.T025NoFactura = T025NoFactura.Text;
                    if (Convert.ToDecimal(T025Importe.Text) > 0)
                    {
                       currRecord.T025Importe = Convert.ToDecimal(T025Importe.Text);
                    }
                    UpdateSaldo();
                    UpdateSaldoGridView();
                    DataContext.T025s.InsertOnSubmit(currRecord);
                    DataContext.SubmitChanges();
                    transaction.Commit();
                    T025Importe.Text = string.Format("{0:C}", currRecord.T025Importe);
                    UpdateGraph();
                 }
                 catch (System.Data.Linq.ChangeConflictException cce)
                 {
                    MessageBox.Show("Error");
                    MainApp.WriteExceptionToLog(cce);
                    transaction.Rollback();
                 }
                 catch (SystemException se)
                 {
                    MainApp.WriteExceptionToLog(se);
                    transaction.Rollback();
                 }
                 finally
                 {
                    DataContext.Connection.Close();
                 }
              }
           }
           // Se esta editando el registro actual
           else
           {
              ///TODO : Si ya esta saldada la factura solicitar codigo de supervisor para hacerle cambios
              try
              {
                 var Indice = CatT011Entity.SelectedIndex;
                 currRecord.T011Entity = (int)CatT011Entity.EditorControl.Rows[CatT011Entity.SelectedIndex].Cells["T011Entity"].Value;
                 currRecord.T025FechaIngreso = T025FechaIngreso.DateTime;
                 currRecord.T025NoFactura = T025NoFactura.Text;
                 T025Importe.Text = T025Importe.Text.Replace("$", "");
                 T025Importe.Text = T025Importe.Text.Replace(",", "");
                 T025Importe.Text = T025Importe.Text.Trim();
                 /// TODO : Validar si se permite el cambio de importe por uno menor cuando ya tiene anticipos
                 /// , ej. que pasa con los anticipos ?
                 currRecord.T025Importe = Convert.ToDecimal(T025Importe.Text);
                 DataContext.SubmitChanges();
                 UpdateSaldo();
                 UpdateSaldoGridView();
                 T025Importe.Text = string.Format("{0:C}", currRecord.T025Importe);
                 UpdateGraph();
              }
              catch (System.Data.Linq.ChangeConflictException cce)
              {
                 MessageBox.Show("Error");
                 MainApp.WriteExceptionToLog(cce);
              }
              catch (SystemException se)
              {
                 MainApp.WriteExceptionToLog(se);
              }
              finally
              {
                 DataContext.Connection.Close();
              }
           }
        }

        private void cxcGraph_DoubleClick(object sender, EventArgs e)
        {
            DetalleCxCWorkBench detalleCxCWorkBench = new DetalleCxCWorkBench() { MdiParent = MainApp.Wb };
            detalleCxCWorkBench.Show();
        }

        private void tsbNvo_Click(object sender, EventArgs e)
        {
           uiHelper.EnableControls(gpoCobros, true, true);
           WorkBenchFilter.Text = string.Empty;
           uiHelper.ClearComboBoxFilter(ref CatT011Entity);
           uiHelper.ClearControls(this.Controls);
           statusMsg.Text = string.Empty;
           currRecord = null;
        }

        private void tsbEdit_Click(object sender, EventArgs e)
        {
           uiHelper.EnableControls(this.gpoCobros, true, false);
           uiHelper.ClearComboBoxFilter(ref CatT011Entity);
           cxcGraph.Series[0].Points.Clear();
        }

        private void CobrosGridView_CellValidating(object sender, CellValidatingEventArgs e)
        {
           if (!DeletingRow && currRecord!=null)
           {
              if (e.Column.Name.Equals("T029Anticipo") && e.OldValue != e.Value)
              {
                 var Anticipo = (decimal)e.Value;
                 var Saldo = 0.0m;
                 if (Anticipo <= 0)
                 {
                    e.Cancel = true;
                 }
                 else
                 {
                    var Anticipos = (from P in DataContext.T029s
                                     where P.T025Id.Equals(currRecord.T025Id)
                                     select P);
                    if (Anticipos != null)
                    {
                       var Suma = Anticipos.Sum(s => (decimal?)s.T029Anticipo) ?? 0m;
                       if (Suma > 0)
                       {
                          Saldo = Suma + Anticipo;
                          if (Saldo > currRecord.T025Importe)
                          {
                             e.Cancel = true;
                          }
                       }
                       else if (Anticipo > currRecord.T025Importe)
                       {
                          e.Cancel = true;
                       }
                    }
                 }
              }
           }
        }

        private void CobrosGridView_CellValidated(object sender, CellValidatedEventArgs e)
        {
           UpdateSaldo();
           UpdateSaldoGridView();
           UpdateGraph();
        }

        private void CobrosGridView_UserDeletingRow(object sender, GridViewRowCancelEventArgs e)
        {
           DeletingRow = true;
           UpdateSaldoGridView();
        }

        private void CobrosGridView_UserDeletedRow(object sender, GridViewRowEventArgs e)
        {
           DeletingRow = false;
           UpdateSaldoGridView();
        }

    }
}
